//p1536 村村通
#include <iostream>
using namespace std;

int unite_set[100000];

int unite(int x, int y, int* s); //用于s中x与y的合并 返回状态码
int find_set(int a, int s[]); //用于在s中寻找a的祖宗 返回祖宗的名字
int counte(int s[], int n); //统计s中一共有多少个互不相干的树干
//我们在这些数据的基础之上 -1 就是最后答案

int main()
{
    //并查集初始化
    while (true)
    {
        int n, m; cin >> n;
        for (int i = 1; i <= n; i ++) unite_set[i] = i; //初始化并查集
        if (n == 0) return 0;
        cin >> m;
        for (int i = 0; i < m; i ++)
        {
            int x, y; cin >> x >> y;
            unite(x, y, unite_set);
        }

        cout << counte(unite_set, n) - 1 << endl;
    }
}

int find_set(int a, int s[])
{
    //找啊找啊找祖宗
    if (s[a] == a) return a; //他自己就是自己的祖宗
    return find_set(s[a], s); //递归查找
}

int unite(int x, int y, int* s)
{
    int a_x = find_set(x, s);
    int b_x = find_set(y, s);
    s[a_x] = b_x;

    return 0;
}

int counte(int s[], int n)
{
    //查找有多少个不通的祖宗
    bool visited[100000] = {false}; // 用于标记已经统计过的祖宗
    int count = 0;
    
    for (int i = 1; i <= n; i++) {
        int root = find_set(i, s); // 找到当前节点的根节点
        if (!visited[root]) {
            visited[root] = true;
            count++;
        }
    }
    
    return count;
}